"""
智能排序模块
用于对视频文件进行智能排序，支持多种命名模式
"""

import re
import logging
from typing import List, Dict, Tuple, Optional, Callable
from dataclasses import dataclass
from enum import Enum
from pathlib import Path

from .file_scanner import VideoFileInfo


class SortMethod(Enum):
    """排序方法枚举"""
    NATURAL = "natural"  # 自然排序（推荐）
    FILENAME = "filename"  # 按文件名字母排序
    SIZE = "size"  # 按文件大小排序
    DATE_CREATED = "date_created"  # 按创建时间排序
    DATE_MODIFIED = "date_modified"  # 按修改时间排序
    DURATION = "duration"  # 按视频时长排序
    CUSTOM = "custom"  # 自定义排序


@dataclass
class SortPattern:
    """排序模式"""
    name: str
    pattern: str  # 正则表达式
    description: str
    extract_func: Callable[[str], Tuple]  # 提取排序键的函数


class SmartVideoSorter:
    """智能视频排序器"""
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        
        # 预定义的排序模式
        self.sort_patterns = [
            SortPattern(
                name="数字段落模式",
                pattern=r"(\d+)-(\d+)",
                description="1-1.mp4, 1-2.mp4, 2-1.mp4 格式",
                extract_func=self._extract_chapter_episode
            ),
            SortPattern(
                name="序号模式",
                pattern=r"(\d+)",
                description="1.mp4, 2.mp4, 10.mp4 格式",
                extract_func=self._extract_simple_number
            ),
            SortPattern(
                name="带前缀序号",
                pattern=r"[^0-9]*(\d+)",
                description="video1.mp4, video2.mp4, video10.mp4 格式",
                extract_func=self._extract_prefixed_number
            ),
            SortPattern(
                name="日期时间模式",
                pattern=r"(\d{4})[_-]?(\d{2})[_-]?(\d{2})(?:[_-](\d{2})[_-]?(\d{2})[_-]?(\d{2}))?",
                description="20241201_143000.mp4 格式",
                extract_func=self._extract_datetime
            ),
            SortPattern(
                name="复杂编号模式",
                pattern=r"(?:第?(\d+)[章节课讲部])?(?:第?(\d+)[节段部分])?",
                description="第1章第2节.mp4 格式",
                extract_func=self._extract_chinese_numbering
            )
        ]
    
    def analyze_naming_pattern(self, video_files: List[VideoFileInfo]) -> Dict:
        """
        分析文件命名模式
        
        Args:
            video_files: 视频文件列表
            
        Returns:
            分析结果
        """
        if not video_files:
            return {"pattern": None, "confidence": 0, "recommended_method": SortMethod.FILENAME}
        
        filenames = [f.filename for f in video_files]
        pattern_scores = {}
        
        # 测试每种模式的匹配度
        for pattern in self.sort_patterns:
            score = self._calculate_pattern_score(filenames, pattern)
            pattern_scores[pattern.name] = {
                "score": score,
                "description": pattern.description
            }
        
        # 找到最佳匹配模式
        best_pattern = max(pattern_scores.items(), key=lambda x: x[1]["score"])
        best_score = best_pattern[1]["score"]
        
        # 推荐排序方法
        if best_score > 0.7:
            recommended_method = SortMethod.NATURAL
        elif best_score > 0.3:
            recommended_method = SortMethod.NATURAL
        else:
            recommended_method = SortMethod.FILENAME
        
        return {
            "pattern": best_pattern[0] if best_score > 0.3 else None,
            "confidence": best_score,
            "recommended_method": recommended_method.value,  # 转换为字符串值
            "all_patterns": pattern_scores,
            "sample_analysis": self._analyze_samples(filenames[:5])
        }
    
    def sort_videos(self, video_files: List[VideoFileInfo], method: SortMethod = SortMethod.NATURAL, 
                   reverse: bool = False, custom_order: Optional[List[str]] = None) -> List[VideoFileInfo]:
        """
        对视频文件进行排序
        
        Args:
            video_files: 视频文件列表
            method: 排序方法
            reverse: 是否逆序
            custom_order: 自定义排序顺序（仅当method=CUSTOM时使用）
            
        Returns:
            排序后的视频文件列表
        """
        if not video_files:
            return []
        
        self.logger.info(f"使用 {method.value} 方法对 {len(video_files)} 个视频文件进行排序")
        
        try:
            if method == SortMethod.NATURAL:
                sorted_files = self._natural_sort(video_files)
            elif method == SortMethod.FILENAME:
                sorted_files = sorted(video_files, key=lambda x: x.filename.lower())
            elif method == SortMethod.SIZE:
                sorted_files = sorted(video_files, key=lambda x: x.size)
            elif method == SortMethod.DATE_CREATED:
                sorted_files = sorted(video_files, key=lambda x: x.created_time)
            elif method == SortMethod.DATE_MODIFIED:
                sorted_files = sorted(video_files, key=lambda x: x.modified_time)
            elif method == SortMethod.DURATION:
                sorted_files = sorted(video_files, key=lambda x: x.duration)
            elif method == SortMethod.CUSTOM and custom_order:
                sorted_files = self._custom_sort(video_files, custom_order)
            else:
                self.logger.warning(f"不支持的排序方法: {method}")
                sorted_files = video_files.copy()
            
            if reverse:
                sorted_files.reverse()
            
            self.logger.info("视频文件排序完成")
            return sorted_files
        
        except Exception as e:
            self.logger.error(f"视频文件排序失败: {e}")
            return video_files.copy()
    
    def _natural_sort(self, video_files: List[VideoFileInfo]) -> List[VideoFileInfo]:
        """自然排序"""
        return sorted(video_files, key=lambda x: self._natural_sort_key(x.filename))
    
    def _natural_sort_key(self, filename: str) -> List:
        """生成自然排序键"""
        # 移除文件扩展名
        name = Path(filename).stem
        
        # 尝试匹配已知模式
        for pattern in self.sort_patterns:
            match = re.search(pattern.pattern, name)
            if match:
                try:
                    return list(pattern.extract_func(name))
                except:
                    continue
        
        # 默认自然排序：将字符串分解为文本和数字部分
        parts = re.split(r'(\d+)', name.lower())
        result = []
        
        for part in parts:
            if part.isdigit():
                result.append(int(part))
            else:
                result.append(part)
        
        return result
    
    def _custom_sort(self, video_files: List[VideoFileInfo], custom_order: List[str]) -> List[VideoFileInfo]:
        """自定义排序"""
        order_map = {filename: i for i, filename in enumerate(custom_order)}
        
        def sort_key(video_file):
            return order_map.get(video_file.filename, len(custom_order))
        
        return sorted(video_files, key=sort_key)
    
    def _calculate_pattern_score(self, filenames: List[str], pattern: SortPattern) -> float:
        """计算模式匹配分数"""
        if not filenames:
            return 0
        
        matches = 0
        for filename in filenames:
            name = Path(filename).stem
            if re.search(pattern.pattern, name):
                matches += 1
        
        return matches / len(filenames)
    
    def _analyze_samples(self, filenames: List[str]) -> List[Dict]:
        """分析样本文件名"""
        results = []
        
        for filename in filenames:
            name = Path(filename).stem
            analysis = {
                "filename": filename,
                "detected_patterns": [],
                "sort_key": self._natural_sort_key(filename)
            }
            
            for pattern in self.sort_patterns:
                match = re.search(pattern.pattern, name)
                if match:
                    analysis["detected_patterns"].append({
                        "pattern": pattern.name,
                        "match": match.groups()
                    })
            
            results.append(analysis)
        
        return results
    
    # 各种提取函数
    def _extract_chapter_episode(self, filename: str) -> Tuple[int, int, str]:
        """提取章节-集数模式：1-1, 1-2, 2-1"""
        match = re.search(r"(\d+)-(\d+)", filename)
        if match:
            chapter = int(match.group(1))
            episode = int(match.group(2))
            return (chapter, episode, filename.lower())
        return (0, 0, filename.lower())
    
    def _extract_simple_number(self, filename: str) -> Tuple[int, str]:
        """提取简单数字模式：1, 2, 10"""
        match = re.search(r"(\d+)", filename)
        if match:
            number = int(match.group(1))
            return (number, filename.lower())
        return (0, filename.lower())
    
    def _extract_prefixed_number(self, filename: str) -> Tuple[int, str]:
        """提取带前缀的数字模式：video1, lesson2"""
        match = re.search(r"[^0-9]*(\d+)", filename)
        if match:
            number = int(match.group(1))
            return (number, filename.lower())
        return (0, filename.lower())
    
    def _extract_datetime(self, filename: str) -> Tuple[int, int, int, int, int, int, str]:
        """提取日期时间模式：20241201_143000"""
        match = re.search(r"(\d{4})[_-]?(\d{2})[_-]?(\d{2})(?:[_-](\d{2})[_-]?(\d{2})[_-]?(\d{2}))?", filename)
        if match:
            year = int(match.group(1))
            month = int(match.group(2))
            day = int(match.group(3))
            hour = int(match.group(4)) if match.group(4) else 0
            minute = int(match.group(5)) if match.group(5) else 0
            second = int(match.group(6)) if match.group(6) else 0
            return (year, month, day, hour, minute, second, filename.lower())
        return (0, 0, 0, 0, 0, 0, filename.lower())
    
    def _extract_chinese_numbering(self, filename: str) -> Tuple[int, int, str]:
        """提取中文编号模式：第1章第2节"""
        chapter_match = re.search(r"第?(\d+)[章节课讲部]", filename)
        section_match = re.search(r"第?(\d+)[节段部分]", filename)
        
        chapter = int(chapter_match.group(1)) if chapter_match else 0
        section = int(section_match.group(1)) if section_match else 0
        
        return (chapter, section, filename.lower())
    
    def get_sort_preview(self, video_files: List[VideoFileInfo], method: SortMethod = SortMethod.NATURAL) -> Dict:
        """
        获取排序预览
        
        Args:
            video_files: 视频文件列表
            method: 排序方法
            
        Returns:
            排序预览信息
        """
        if not video_files:
            return {"original": [], "sorted": [], "changes": []}
        
        original_order = [(i, f.filename) for i, f in enumerate(video_files)]
        sorted_files = self.sort_videos(video_files, method)
        sorted_order = [(i, f.filename) for i, f in enumerate(sorted_files)]
        
        # 检测变化
        changes = []
        filename_to_new_index = {f.filename: i for i, f in enumerate(sorted_files)}
        
        for old_index, filename in original_order:
            new_index = filename_to_new_index.get(filename, old_index)
            if old_index != new_index:
                changes.append({
                    "filename": filename,
                    "old_position": old_index + 1,
                    "new_position": new_index + 1,
                    "change": new_index - old_index
                })
        
        return {
            "original": original_order,
            "sorted": sorted_order,
            "changes": changes,
            "total_changes": len(changes)
        }


# 便捷函数
def analyze_video_naming(video_files: List[VideoFileInfo]) -> Dict:
    """
    便捷函数：分析视频文件命名模式
    
    Args:
        video_files: 视频文件列表
        
    Returns:
        分析结果
    """
    sorter = SmartVideoSorter()
    return sorter.analyze_naming_pattern(video_files)


def sort_videos_smart(video_files: List[VideoFileInfo], method: SortMethod = SortMethod.NATURAL) -> List[VideoFileInfo]:
    """
    便捷函数：智能排序视频文件
    
    Args:
        video_files: 视频文件列表
        method: 排序方法
        
    Returns:
        排序后的视频文件列表
    """
    sorter = SmartVideoSorter()
    return sorter.sort_videos(video_files, method)